<template>
  <q-list bordered class="mb-2px">
    <q-expansion-item label="搜索" switch-toggle-side>
      <q-card>
        <q-card-section>
          <q-form ref="formRef" @submit="handleSubmit" @reset="handleReset">
            <div class="row q-col-gutter-md justify-between">
              <!-- 1. 遍历Schema 渲染表单项 -->
              <div class="row q-col-gutter-md justify-start">
                <div v-for="item in schema" :key="item.field">
                  <!-- 输入框 -->
                  <q-input
                    v-if="item.type === 'input'"
                    v-model="formData[item.field]"
                    :label="item.label"
                    :placeholder="item.placeholder"
                    :rules="item.rules"
                    v-bind="item.componentProps"
                  />

                  <!-- 选择框 -->
                  <q-select
                    v-if="item.type === 'select'"
                    v-model="formData[item.field]"
                    :label="item.label"
                    :options="item.options"
                    :rules="item.rules"
                    v-bind="item.componentProps"
                  />
                  <!-- 日期选择器 -->
                  <q-input
                    v-if="item.type === 'date'"
                    v-model="formData[item.field]"
                    :label="item.label"
                    :placeholder="item.placeholder"
                    :rules="item.rules"
                    v-bind="item.componentProps"
                    class="w-150px"
                  >
                    <template v-slot:append>
                      <q-icon name="event" class="cursor-pointer">
                        <q-popup-proxy cover transition-show="scale" transition-hide="scale">
                          <q-date v-model="formData[item.field]" today-btn mask="YYYY-MM-DD">
                            <div class="row items-center justify-end">
                              <q-btn v-close-popup label="关闭" color="primary" flat />
                            </div>
                          </q-date>
                        </q-popup-proxy>
                      </q-icon>
                    </template>
                  </q-input>
                </div>
              </div>
              <!-- 2. 操作按钮区域  -->
              <div>
                <q-btn label="查询" type="submit" color="primary" outline class="q-mr-sm" />
                <q-btn label="重置" type="reset" color="primary" dense flat />
              </div>
            </div>
          </q-form>
        </q-card-section>
      </q-card>
    </q-expansion-item>
  </q-list>
</template>

<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import type { QForm } from 'quasar'
import type { MiniFormSchema } from './types'

defineOptions({
  name: 'MiniQueryForm',
})

// Props and Emits

const props = defineProps<{
  schema: readonly MiniFormSchema[]
}>()

const emit = defineEmits<{
  (e: 'submit', formData: Record<string, any>): void
  (e: 'reset'): void
}>()

// state

const formRef = ref<QForm | null>(null)
const formData = ref<Record<string, any>>({})

// logic
/**
 * 根据Schema 初始化表单数据
 */

const initFormData = () => {
  const data: Record<string, any> = {}
  props.schema.forEach((item) => {
    // 使用??(空值合并运算符)确保defaultValue 为0，false 等有效值时被正确赋值
    data[item.field] = item.defaultValue ?? null
  })
  formData.value = data
}

/**
 * 提交处理函数
 */

const handleSubmit = async () => {
  const isValid = await formRef.value?.validate()
  if (isValid) {
    // 过滤掉值为null 或undefined的字段再提交
    console.log('formData.value::', formData.value)
    const finalData = Object.entries(formData.value).reduce(
      (acc, [key, value]) => {
        if (value !== null && value !== undefined) {
          acc[key] = value
        }
        return acc
      },
      {} as Record<string, any>,
    )
    emit('submit', finalData)
  }
}

/**
 * 重置处理函数
 */

const handleReset = () => {
  initFormData() // 重置为默认值
  formRef.value?.resetValidation() // 清除验证状态
  emit('reset')
}

// 使用watchEffect 可以在schema prop 变化时自动重新初始化表单
watchEffect(initFormData)
</script>

<style scoped></style>
